package de.jtserver.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.google.appengine.api.datastore.Blob;

import de.jtserver.EMF;

public class SmallBlobHelper {

	public byte[] readSmalltalk(String owner) {
		EntityManager em = EMF.get().createEntityManager();
		JTalkScript jtScript = null;

		Query q = em.createQuery("select from " + JTalkScript.class.getName() + " where owner = '" + owner
				+ "' order by id desc limit 1");
		List l = q.getResultList();
		jtScript = (JTalkScript) l.get(0);
		if (jtScript != null) {
			// initialize OneToMany since the EAGER-Annotations seems to be
			// ignored
			jtScript.getSmalltalk();
			byte[] data = createByteArray(jtScript.getSmalltalk());
			em.clear();
			em.close();
			return data;
		}
		em.clear();
		em.close();
		return null;
	}


	public boolean saveSmalltalk(byte[] bytes, String owner) {
		EntityManager em = EMF.get().createEntityManager();

		Query q = em.createQuery("select from " + JTalkScript.class.getName() + " where owner = '" + owner
				+ "' order by id desc limit 1");
		List l = q.getResultList();

		JTalkScript jtScript = (JTalkScript) l.get(0);
		JTalkScript jtScriptNeu = new JTalkScript();
		jtScriptNeu.setOwner(jtScript.getOwner());
		jtScriptNeu.setScript(jtScript.getScript());
		
		em.getTransaction().begin();
		if (jtScript != null) {
			for (SmallBlob sb : jtScript.getSmalltalk()) {
				em.remove(sb);
			}
			em.remove(jtScript);
		}
		em.getTransaction().commit();

		List<SmallBlob> smallblobs = createSmallBlobs(bytes);
		jtScriptNeu.setSmalltalk(smallblobs);

		em.getTransaction().begin();
		em.persist(jtScriptNeu);
		em.getTransaction().commit();
		em.clear();
		em.close();

		return true;
	}

	public List<SmallBlob> createSmallBlobs(byte[] data) {
		int datalength = 500000;
		List<SmallBlob> smallblobs = new ArrayList<SmallBlob>();
		byte[] saveData = data;
		int offset = 0;
		Long counter = 0l;
		while (offset < saveData.length) {
			byte[] smalldata = new byte[saveData.length - offset > datalength ? datalength : saveData.length - offset];
			for (int i = 0; i < smalldata.length; i++) {
				smalldata[i] = saveData[offset];
				offset += 1;
			}
			SmallBlob smallblob = new SmallBlob(counter, new Blob(smalldata));
			counter++;
			smallblobs.add(smallblob);
		}

		return smallblobs;
	}

	public byte[] createByteArray(List<SmallBlob> smallblobs) {
		int size = 0;

		Comparator<SmallBlob> compBlob = new Comparator<SmallBlob>() {
			@Override
			public int compare(SmallBlob sm1, SmallBlob sm2) {
				if (sm1.getOrder() < sm2.getOrder()) {
					return -1;
				} else if (sm1.getOrder() > sm2.getOrder()) {
					return 1;
				}
				return 0;
			}
		};

		Collections.sort(smallblobs, compBlob);

		for (SmallBlob smallblob : smallblobs) {
			byte[] decoded = null;
			decoded = smallblob.getData().getBytes();
			size += decoded.length;
		}
		byte[] data = new byte[size];

		int offset = 0;
		for (SmallBlob smallblob : smallblobs) {
			byte[] decoded = null;
			decoded = smallblob.getData().getBytes();
			for (int i = 0; i < decoded.length; i++) {
				data[offset] = decoded[i];
				offset += 1;
			}
		}

		return data;
	}

}
